package sqlClass.appClass;

import general.appClass.SystemInfo;
import general.dbClass.DBCategory;
import general.dbClass.DBKeyword;
import general.dbClass.DBThumbInfo;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import sqlClass.daoClass.DaoGet;

/**
 * Servlet implementation class SearchApp
 */
@WebServlet("/SearchApp")
public class SearchApp extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private static ArrayList<DBThumbInfo> lastSearchResult = null;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public SearchApp() {
		super();
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		this.doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("image/jpeg");
		response.setHeader("Pragma", "No-Cache");
		response.setHeader("Cache-Control", "No-Cache");
		response.setDateHeader("Expires", 0);

		//System Information Manage Class
		Connection 	conn = SystemInfo.getConn(request);
		
		String searchFor = request.getParameter("searchFor");
		if (searchFor != null && searchFor.equals("thumbs")) {
			this.getThumbsBySearch(conn, request, response);
			return;
		}
		
		if (searchFor != null && searchFor.equals("allCategorieAndKeyword")) {
			this.getAllCategorieAndKeywords(conn, request, response);
			return;
		}
		
		if (searchFor != null && searchFor.equals("categories")) {
			this.getAllCategorie(conn, request, response);
			return;
		}
		
		if (searchFor != null && searchFor.equals("prepare")) {
			try {

				ArrayList<DBCategory> categories = DaoGet.getAllCategories(conn);
				request.setAttribute("categories", categories);
				ArrayList<DBKeyword> keywords = DaoGet.getAllKeywords(conn);
				request.setAttribute("keywords", keywords);
				ArrayList<String> formats = DaoGet.getAllOrientation(conn);
				request.setAttribute("formats", formats);
				ArrayList<String> exposureProgram = DaoGet
						.getAllExposureProgram(conn);
				request.setAttribute("exposureProgram", exposureProgram);
				ArrayList<String> exposureMode = DaoGet.getAllExposureMode(conn);
				request.setAttribute("exposureMode", exposureMode);
				ArrayList<String> exposureTime = DaoGet.getAllExposureTime(conn);
				request.setAttribute("exposureTime", exposureTime);
				ArrayList<String> colorSpace = DaoGet.getAllColorSpace(conn);
				request.setAttribute("colorSpace", colorSpace);
				ArrayList<String> fnumber = DaoGet.getAllFnumber(conn);
				request.setAttribute("fnumber", fnumber);
				ArrayList<String> makes = DaoGet.getAllCameraMake(conn);
				request.setAttribute("makes", makes);
				ArrayList<String> models = DaoGet.getAllCameraModel(conn);
				request.setAttribute("models", models);
				String url = response.encodeURL("/filter.jsp");
				RequestDispatcher dispatcher = getServletContext()
						.getRequestDispatcher(url);
				dispatcher.forward(request, response);

			} catch (SQLException e) {
				e.printStackTrace();
			}

			return;
		}
	}

	private void getAllCategorie(Connection conn, HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		try {
			ArrayList<DBKeyword> keywords = DaoGet.getAllKeywords(conn);
			ArrayList<DBCategory> categories = DaoGet.getAllCategories(conn);
			request.setAttribute("keywords", keywords);
			request.setAttribute("categories", categories);
			String url = response.encodeURL("/category.jsp");
			RequestDispatcher dispatcher = getServletContext()
					.getRequestDispatcher(url);
			dispatcher.forward(request, response);
		} catch (SQLException e) {
			e.printStackTrace();
			String message = e.getMessage();
			request.setAttribute("Quelle", "connect");
			request.setAttribute("Error", message);
			String url = response.encodeURL("/errorInfo.jsp");
			RequestDispatcher dispatcher = getServletContext()
					.getRequestDispatcher(url);
			dispatcher.forward(request, response);
		}

	}

	private void getAllCategorieAndKeywords(Connection con,
			HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		try {
			ArrayList<DBKeyword> keywords = DaoGet.getAllKeywords(con);
			ArrayList<DBCategory> categories = DaoGet.getAllCategories(con);

			request.setAttribute("keywords", keywords);
			request.setAttribute("categories", categories);

			String url = response.encodeURL("/uploadImg.jsp");
			RequestDispatcher dispatcher = getServletContext()
					.getRequestDispatcher(url);
			dispatcher.forward(request, response);
		} catch (SQLException e) {
			e.printStackTrace();
			String message = e.getMessage();
			request.setAttribute("Quelle", "connect");
			request.setAttribute("Error", message);
			String url = response.encodeURL("/errorInfo.jsp");
			RequestDispatcher dispatcher = getServletContext()
					.getRequestDispatcher(url);
			dispatcher.forward(request, response);
		}

	}

	private boolean checkValid(HttpServletRequest request, int i, int j) {
		String name = request.getParameter("searchItemName" + i + j);
		String compare = request.getParameter("searchItemCompare" + i + j);
		String value = request.getParameter("searchItemValue" + i + j);
		if (name != null && compare != null && value != null && !name.equals("")
				&& !compare.equals("") && !value.equals("")) {
			return true;
		} else {
			return false;
		}
	}

	private void getThumbsBySearch(Connection conn, HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		boolean isLogin = true;
		boolean furtherSearch = request.getParameter("furtherSearch") != null;
		//HttpSession session = request.getSession(true);
		//String usr = (String) session.getAttribute("usr");
		ArrayList<DBThumbInfo> thumbs = null;
		ArrayList<DBThumbInfo> thumbsTemp = null;
		
		//if (usr != null && usr.equals(LoginApp.loginName)) {
		//	isLogin = true;
		//}
		
		//System.out.println(request.getParameter("in"));
		if (request.getParameter("in") != null
				&& request.getParameter("in").equals("category")) {
			int ktnr = Integer.parseInt(request.getParameter("ktnr"));
			try {
				thumbs = DaoGet.getThumbsByCategory(conn, ktnr, isLogin);
			} catch (SQLException e) {
				e.printStackTrace();
			}
			request.setAttribute("title",
					"Kategorie: " + request.getParameter("name"));

		}
		if (request.getParameter("in") != null
				&& request.getParameter("in").equals("keyword")) {
			int kwnr = Integer.parseInt(request.getParameter("kwnr"));
			try {
				thumbs = DaoGet.getThumbsByKeywordId(conn, kwnr, isLogin);
			} catch (SQLException e) {
				e.printStackTrace();
			}
			request.setAttribute("title",
					"Schlagwort: " + request.getParameter("word"));

		}	
		if (request.getParameter("in") != null
				&& (request.getParameter("in").equals("search") || request
						.getParameter("in").equals("all"))) {
			int i = 0;
			int j = 0;
			// array valid keep the count of valid search-item in each row
			int[] valid = new int[9];
			int count = 0;
			String sql = "";
			String sqlAll = "(select DBPic.bnr, DBPic.name from DBPic)";
			for (i = 0; i < 4; i++) {
				for (j = 0; j < 4; j++) {
					if (checkValid(request, i, j)) {
						valid[i]++;
					}
				}
				count += valid[i];
			}
			if (count == 0) {
				sql = sqlAll;
			}
			if (count > 0) {
				String name = null;
				String compare = null;
				String value = null;
				for (i = 0; i < 9; i++) {
					if (valid[i] > 0) {
						if (i > 0) {
							sql += " UNION ";
						}
						sql += " ( ";
						for (j = 0; j < 9; j++) {
							name = request.getParameter("searchItemName" + i
									+ j);
							compare = request.getParameter("searchItemCompare"
									+ i + j);
							value = request.getParameter("searchItemValue" + i
									+ j);
							if (checkValid(request, i, j)) {
								if (j > 0) {
									sql += " INTERSECT ";
								}
								if (name.equals("kwnr")) {
									if (compare.equals("=")){
										sql += "(select DBPic.bnr, DBPic.name from DBPic,Haben where "
											+ "DBPic.bnr = Haben.bnr and Haben.kwnr "
											+ compare + value + ")";	
									}else if (compare.equals("!=")){
										sql+= "(select DBPic.bnr, DBPic.name from DBPic MINUS (select distinct DBPic.bnr, DBPic.name from DBPic,Haben where "
											+ "DBPic.bnr = Haben.bnr and Haben.kwnr"
											+ " = " + value + "))";
									}
									
								} else if (name.equals("ktnr")) {
									if (compare.equals("=")){
										sql += "(select DBPic.bnr, DBPic.name from DBPic,Zuordnen where "
											+ "DBPic.bnr = Zuordnen.bnr and Zuordnen.ktnr "
											+ compare + value + ")";	
									}else if (compare.equals("!=")){
										sql += "(select DBPic.bnr, DBPic.name from DBPic MINUS (select distinct DBPic.bnr, DBPic.name from DBPic,Zuordnen where "
											+ "DBPic.bnr = Zuordnen.bnr and Zuordnen.ktnr"
											+ " = " + value + "))";
									}
									
								} else if (name.equals("imgHeight")
										|| name.equals("imgWidth")
										|| name.equals("exifImgWidth")
										|| name.equals("exifImgHeight")) {
									sql += "(select DBExifValue.bnr, DBPic.name from DBExifValue, DBPic where DBExifValue.bnr = DBPic.bnr and "
											+ name + compare + value + ")";
								} else if (name.equals("timeOriginal")
										|| name.equals("timeDigitized")) {
									sql += "(select DBExifValue.bnr, DBPic.name from DBExifValue, DBPic where DBExifValue.bnr = DBPic.bnr and "
											+ name
											+ compare
											+ "to_date('"
											+ value
											+ "','yyyy-MM-dd')"
											+ ")";
								} else if (name.equals("exposureTime")) {
									value = value.replace(" sec", "");
									float exposureTimeValue;
									float e = (float) 0.00001;
									if (value.indexOf('/') >= 0) {
										exposureTimeValue = Float
												.parseFloat(value.split("/")[0])
												/ Float.parseFloat(value
														.split("/")[1]);
									} else {
										exposureTimeValue = Float
												.parseFloat(value);
									}
									if (compare.equals(">=")) {
										sql += "(select DBExifValue.bnr, DBPic.name from DBExifValue, DBPic where DBExifValue.bnr = DBPic.bnr and "
												+ name
												+ compare
												+ (exposureTimeValue - e) + ")";
									}
									if (compare.equals("<=")) {
										sql += "(select DBExifValue.bnr, DBPic.name from DBExifValue, DBPic where DBExifValue.bnr = DBPic.bnr and "
												+ name
												+ compare
												+ (exposureTimeValue + e) + ")";
									}
									if (compare.equals("=")) {
										sql += "(select DBExifValue.bnr, DBPic.name from DBExifValue, DBPic where DBExifValue.bnr = DBPic.bnr and "
												+ name
												+ ">"
												+ (exposureTimeValue - e)
												+ " and "
												+ name
												+ "<"
												+ (exposureTimeValue + e) + ")";
									}
									if (compare.equals("!=")) {
										sql += "(select DBExifValue.bnr, DBPic.name from DBExifValue, DBPic where DBExifValue.bnr = DBPic.bnr and "
												+ name
												+ compare
												+ exposureTimeValue + ")";
									}
								} else {
									sql += "(select DBExif.bnr, DBPic.name from DBExif, DBPic where DBExif.bnr = DBPic.bnr and "
											+ name
											+ compare
											+ "'"
											+ value
											+ "')";
								}
							}
						}
						sql += " ) ";
					}
				}
			}
			//System.out.println(sql);

			try {
				thumbs = DaoGet.getThumbsBySearch(conn, sql, isLogin);
			} catch (SQLException e) {
				e.printStackTrace();
			}
			thumbsTemp = thumbs;
			if (furtherSearch && lastSearchResult != null) {
				thumbs = DBThumbInfo.intersect(thumbs, lastSearchResult);
			}
			lastSearchResult = thumbsTemp;
			
			request.setAttribute("title", "Filtern Ergebnis");
			
			if (request.getParameter("in") != null
					&& request.getParameter("in").equals("all")) {
				request.setAttribute("title", "Alle Thumbnails");
			}
		}
		request.setAttribute("Thumbs", thumbs);
		request.setAttribute("type", "thumbs");
		request.setAttribute("count", thumbs.size());
		String url = response.encodeURL("/showThumbs.jsp");
		RequestDispatcher dispatcher = getServletContext()
				.getRequestDispatcher(url);
		dispatcher.forward(request, response);
	}
}
